﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using CsGL.OpenGL;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using Model3D;

namespace OpenCV_STD
{
    partial class OpenGLBase : OpenGLControl
    {
        #region 数据成员
        Timer Timer_GLupdate = new Timer();//窗口重绘计时器

        //H3DModel car;

        public double eyeX = 4;
        public double eyeY = -2;
        public int w = 8;
        public int h = 6;
        public int d = 4;
        public float[] LightAmbient = new float[4] { 0.5f, 0.5f, 0.5f, 1.0f };
        public float[] LightDiffuse = new float[4] { 1.0f, 1.0f, 1.0f, 1.0f };
        public float[] LightPosition = new float[4] { 0.0f, 0.0f, 20.0f, 1.0f };
        #endregion

        #region 构造函数及刷新GL事件初始化
        public OpenGLBase()
        {
            /************************************************************************/
            /* OpenGL屏幕刷新计时器                                   */
            /************************************************************************/
            this.Timer_GLupdate.Tick += new EventHandler(Timer_GLupdate_Tick);
            this.Timer_GLupdate.Interval = 20;
            this.Timer_GLupdate.Start();
            /************************************************************************/
            /* 按键回调          */
            /************************************************************************/
            this.KeyDown += new KeyEventHandler(OpenGLBase_KeyDown);
        }
        private void OpenGLBase_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                /************************************************************************/
                /* 场景控制                                                                     */
                /************************************************************************/
                case Keys.D:
                    break;
                case Keys.A:
                    break;
                case Keys.S:
                    break;
                case Keys.W:
                    break;
                default:
                    break;

            }
        }
        private void Timer_GLupdate_Tick(object sender, EventArgs e)
        {
            this.Invalidate();
        }
        #endregion

        #region 窗体重绘
        /// <summary>
        /// 视口改变大小时重新设置视口和绘图
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            GL.glViewport(0, 0, this.Bounds.Width, this.Bounds.Height);
            GL.glMatrixMode(GL.GL_PROJECTION);
            GL.glLoadIdentity();
            GL.gluPerspective(40.0f, (float)this.Bounds.Width / (float)this.Bounds.Height, 0.1f, 500.0f);
            GL.glMatrixMode(GL.GL_MODELVIEW);
        }
        /// <summary>
        /// OnPaint方法处理Paint事件
        /// </summary>
        /// <param name="pevent"></param>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs pevent)
        {
            base.OnPaint(pevent);
            //ToDo:可加入自己的设计代码
        }

        #endregion
        /************************************************************************/
        /* OpenGL初始化                                                                 */
        /************************************************************************/
        protected override void InitGLContext()
        {
            base.InitGLContext();

            GL.glMatrixMode(GL.GL_PROJECTION);//选择投影矩阵
            GL.glLoadIdentity();//重设投影矩阵
            GL.gluPerspective(17.0, ((double)(this.Width) / (double)(this.Height)), 1.0, 1000.0);//调整视口大小
            GL.glMatrixMode(GL.GL_MODELVIEW);//选择模型观察矩阵
            GL.glLoadIdentity();//重置模型观察矩阵
            GL.glShadeModel(GL.GL_SMOOTH);						// 启用阴影平滑
            GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
            GL.glEnable(GL.GL_TEXTURE_2D);
            GL.glEnable(GL.GL_COLOR_MATERIAL);
            GL.glEnable(GL.GL_LIGHTING);
            GL.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, LightAmbient);
            GL.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, LightDiffuse);
            GL.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, LightPosition);
            GL.glEnable(GL.GL_LIGHT1);


            //tex = new OpenGLTexture2D("1.png");
            GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);	// 线形滤波
            GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);	// 线形滤波

            //car = H3DModel.FromFile("3DS\\019.3ds");
        }

        private void DrawGrids(int x, int y)
        {
            GL.glBegin(GL.GL_QUADS);
            GL.glVertex2d(0.0, 0.0);
            GL.glVertex2d((double)x, 0.0);
            GL.glVertex2d((double)x, (double)y);
            GL.glVertex2d(0.0, (double)y);
            GL.glEnd();

            GL.glBegin(GL.GL_LINES);
            for (int i = 1; i < x; i++)
            {
                GL.glVertex2d((double)i, 0.0);
                GL.glVertex2d((double)i, (double)y);
            }

            for (int i = 1; i < y; i++)
            {
                GL.glVertex2d(0.0, (double)i);
                GL.glVertex2d((double)x, (double)i);
            }
            GL.glEnd();
        }

        private void DrawBox()
        {
            GL.glTranslated(-w / 2.0, -h / 2.0, 0.0);
            GL.glRotated(90.0, 0.0, 1.0, 0.0);
            DrawGrids(d, h);
            GL.glTranslated((double)d, 0.0, 0.0);
            GL.glRotated(-90.0, 0.0, 1.0, 0.0);
            DrawGrids(w, h);
            GL.glPushMatrix();
            GL.glRotated(90.0, 1.0, 0.0, 0.0);
            DrawGrids(w, d);
            GL.glTranslated(0.0, 0.0, -(double)h);
            DrawGrids(w, d);
            GL.glPopMatrix();
            GL.glTranslated((double)w, 0.0, 0.0);
            GL.glRotated(-90.0, 0.0, 1.0, 0.0);
            DrawGrids(d, h);
        }

        public override void glDraw()
        {
            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);			// 清除屏幕及深度缓存
            GL.glMatrixMode(GL.GL_PROJECTION);//选择投影矩阵
            GL.glLoadIdentity();//重设投影矩阵
            //double R = 200.0;
            //double px = Math.Sin((eyeX - 160) / 360.0 * 2 * Math.PI) * Math.Cos((eyeY - 120) / 360 * 2 * Math.PI) * R;
            //double py = Math.Cos((eyeX - 160) / 360.0 * 2 * Math.PI) * Math.Cos((eyeY - 120) / 360 * 2 * Math.PI) * R;
            //double pz = Math.Sin((eyeY - 120) / 360.0 * 2 * Math.PI) * R;
            GL.glFrustum(-w / 2.0 - eyeX, w / 2.0 - eyeX, -h / 2.0 - eyeY, h / 2.0 - eyeY, 60.0, 100.0);
            GL.glMatrixMode(GL.GL_MODELVIEW);//选择模型观察矩阵
            GL.glLoadIdentity();//重置模型观察矩阵
            GL.gluLookAt(eyeX, eyeY, 60.0, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0);
            GL.glPushMatrix();
            GL.glColor3d(1.0, 1.0, 1.0);
            GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
            DrawBox();
            GL.glPopMatrix();
            //GL.glTranslated(0.0, 0.0, -2.0);
            GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
            GL.glColor3d(1.0, 0.0, 0.0);
            GL.glutSolidCube(2.0);

            //tex.Bind();
            //GL.glBegin(GL.GL_QUADS);
            //GL.glTexCoord2d(0f, 0f); GL.glVertex3f(-1.0f, -1.0f, 1.0f);
            //GL.glTexCoord2d(0f, 1f); GL.glVertex3f(-1.0f, 1.0f, 1.0f);
            //GL.glTexCoord2d(1f, 1f); GL.glVertex3f(1.0f, 1.0f, 1.0f);
            //GL.glTexCoord2d(1f, 0f); GL.glVertex3f(1.0f, -1.0f, 1.0f);
            //GL.glEnd();

            GL.glFlush();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }
    }
}
